package com.zs.grain.device

import android.content.Context
import android.util.SparseArray
import androidx.lifecycle.MutableLiveData
import com.xnkj1688.semplibrary.entity.Adjustment
import com.zslibrary.BusMaster.*
//import com.zslibrary.Component.
import com.zslibrary.Enum.BoardId
import com.zslibrary.Enum.ProducingStatusDefine
import com.zslibrary.Enum.StateDefine
import com.zslibrary.Protocol.Machine
import com.zslibrary.Structure.*
import java.io.File


class GrainDevice(val mContext: Context) {
    //private lateinit var oldComponentList:List<GateStruct>
    val busMaster: BusMaster
    val isOpen: Boolean = true
    val isHotting: Boolean
        get() = busMaster.isThereGateSuspend
    val isThereGateDepleted: Boolean
        get() {
            try {
                return busMaster.isThereGateDepleted
            } catch (e: Throwable) {
                e.printStackTrace()
            }
            return false
        }

    val unvaliableComponents: Array<Int>
        get() {
            var list = ArrayList<Int>()
            var array = busMaster.getUnvaliableComponent()
            //if(oldComponentList != array) oldComponentList = array
            if (array != null) {
                for (item in array)
                    list.add(item.componentId.toInt())
            }
            return list.toTypedArray()
        }

    init {
        busMaster = BusMaster.getInstance(mContext)
    }

    fun open(deiveName: String, configPath: String, adjustments: Array<Adjustment>) {
        val list = ArrayList<UserAdjustmentStruct>()
        for (item in adjustments) {
            var adj = UserAdjustmentStruct()
            adj.componentId = item.componentId.toShort()
            adj.adjustmentId = item.adjustmentId.toByte()
            adj.value = item.value.toShort()
            adj.productId = -1
            adj.fluid = 0
            list.add(adj)
        }
        busMaster.startBus(deiveName, configPath, list.toTypedArray())
    }

    fun close() {
        busMaster.finishBus()
    }

    val ioAppVersion: String
        get() {
            try {
                var array = busMaster.softwareVersion
                for (item in array) {
                    if (item.boradAddress == BoardId.IO_BOARD && item.type == 0)
                        return BoardId.getBoardName(BoardId.IO_BOARD) + "(app):" + item.version
                }
            } catch (e: Throwable) {
                e.printStackTrace()
                return e.message ?: "Error"
            }
            return ""
        }
    val ioBootVersion: String
        get() {
            try {
                var array = busMaster.softwareVersion
                for (item in array) {
                    if (item.boradAddress == BoardId.IO_BOARD && item.type == 1)
                        return BoardId.getBoardName(BoardId.IO_BOARD) + "(boot):" + item.version
                }
            } catch (e: Throwable) {
                e.printStackTrace()
                return e.message ?: "Error"
            }
            return ""
        }
    val cupAppVersion: String
        get() {
            try {
                var array = busMaster.softwareVersion
                for (item in array) {
                    if (item.boradAddress == BoardId.CUP_BOARD && item.type == 0)
                        return BoardId.getBoardName(BoardId.CUP_BOARD) + "(app):" + item.version
                }
            } catch (e: Throwable) {
                e.printStackTrace()
                return e.message ?: "Error"
            }
            return ""
        }
    val cupBootVersion: String
        get() {
            try {
                var array = busMaster.softwareVersion
                for (item in array) {
                    if (item.boradAddress == BoardId.CUP_BOARD && item.type == 1)
                        return BoardId.getBoardName(BoardId.CUP_BOARD) + "(boot):" + item.version
                }
            } catch (e: Throwable) {
                e.printStackTrace()
                return e.message ?: "Error"
            }
            return ""
        }

    val hardwareVersion: String
        get() {
            var version = ""
            try {
                var array = busMaster.hardwareVersion
                for (item in array) {
                    version += BoardId.getBoardName(item.boardAdress) + ":" + item.version + "\t\t"
                }
            } catch (e: Throwable) {
                e.printStackTrace()
                return e.message ?: "Error"
            }
            return version
        }

    val craftVersion: String
        get() {
            var version = ""
            try {
//                var array = busMaster.hardwareVersion
//                for (item in array) {
//                    version += BoardId.getBoardName(item.boardAdress) + ":" + item.version + "\t\t"
//                }
            } catch (e: Throwable) {
                e.printStackTrace()
                return e.message ?: "Error"
            }
            return version
        }

    val components: SparseArray<ComponentStruct>?
        get() = busMaster.getAllComponents()

//    val cardNums :SparseArray<CardStruct>?
//        get() = BusNfc.OnDetectCard {  }

    val errors: Array<Pair<EnumError, Boolean>>
        get() {
            var list = ArrayList<Pair<EnumError, Boolean>>()
            val array = HandleError.getAllErrors()
            if (array != null) {
                for (item in array) {
                    list.add(Pair(EnumError.valueOf(item.errorCode), item.isFatal))
                }
            }
            return list.toTypedArray()
        }

    fun getTestInfos(componentId: Int): Array<TestBean> {
        var testInfos = busMaster.getTestInfo(componentId)
        var list = ArrayList<TestBean>()
        if (testInfos != null) {
            for (item in testInfos) {
                var bean = TestBean()
                bean.index = item.index
                bean.name = item.name
                bean.type = item.type
                list.add(bean)
            }
        }
        return list.toTypedArray()
    }

    fun testComponent(componentId: Int, funcId: Int): Boolean {
        return busMaster.componentTest(componentId, funcId)
    }

    fun saveCalibration(componentyId: Int, times: Int, value: Int): Adjustment {
        var adjLocal = busMaster.getCalibrationInfo(componentyId)
        var adjValue = value * Math.pow(10.0, (adjLocal.decPoint - 1).toDouble())
        var adjUser = busMaster.setCalibrationValue(componentyId, times, adjValue.toInt())
        var adjustment = Adjustment()
        adjustment.componentId = adjUser.componentId.toLong()
        adjustment.adjustmentId = adjUser.adjustmentId.toLong()
        adjustment.value = adjUser.value.toInt()
        return adjustment
    }

    fun setAllUserAdjustments(adjustments: Array<Adjustment>) {
        var list = ArrayList<UserAdjustmentStruct>()
        for (item in adjustments) {
            var adj = UserAdjustmentStruct()
            adj.componentId = item.componentId.toShort()
            adj.adjustmentId = item.adjustmentId.toByte()
            adj.value = item.value.toShort()
            adj.productId = -1
            adj.fluid = 0
            list.add(adj)
        }
        busMaster.setAllUserAdjustment(list.toTypedArray())
    }

    fun getAdjustments(componentId: Int): Array<AdjustBean> {
        var list = ArrayList<AdjustBean>()
        var adjustments = busMaster.getComponentAdjustments(componentId)
        if (adjustments != null) {
            adjustments = adjustments.filter { x -> x != null }.toTypedArray()
            for (item in adjustments) {
                var adjust = AdjustBean()
                adjust.id = item.adjustmentId
                adjust.title = "${item.name}"
                adjust.min = item.minimum.toDouble()
                adjust.max = item.maxmum.toDouble()
                adjust.value = item.value.toDouble()
                adjust.decPoint = item.decPoint
                adjust.unitType = item.unitType
                list.add(adjust)
            }
        }
        return list.toTypedArray()
    }

    fun clearAllError() = HandleError.clearAllError()

    val updateProgress: Int
        get() = busMaster.updateProgress

    fun updateSoftware(boardId: EnumBoard, type: EnumBoardType, filePath: String): Int {

        return busMaster.updateSoftware(boardId.value, type.value, filePath)
    }

    fun makeProduct(receipes: Array<ReceipeBean>, craftId: Int): Boolean {
        var list = ArrayList<ConfigRecipeStrcut>()
        for (item in receipes) {
            var receipe = ConfigRecipeStrcut()
            receipe.componentId = item.componentId
            receipe.dosage = item.dosage
            receipe.property = item.property
            list.add(receipe)
        }
        return busMaster.startMakeProduct(list.toTypedArray(), craftId)
    }

    val producingProgress
        get() = busMaster.producingProgress
    val producingStatus: EnumProducingStatus
        get() {
            var status = busMaster.getProducingStatus()
            when (status) {
                ProducingStatusDefine.P_FINISH -> return EnumProducingStatus.FINISH
                ProducingStatusDefine.P_TAKE_AWAY -> return EnumProducingStatus.TAKE_AWAY
            }
            return EnumProducingStatus.PRODUCING
        }

//    val deviceStatus:EnumDeviceStatus
//        get() {
//            var status = busMaster.mStateMachine.currentState
//            when(status){
//                StateDefine.STATE_BUSY -> return EnumDeviceStatus.BUSY
//            }
//            return EnumDeviceStatus.IDLE
//        }
}